package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"

	"websocket-binance/internal/binance"
	"websocket-binance/internal/config"
	"websocket-binance/internal/ws"
)

func main() {
	// 解析命令行参数
	configPath := flag.String("config", "config/config.yaml", "配置文件路径")
	flag.Parse()

	// 加载配置文件
	cfg, err := config.LoadConfig(*configPath)
	if err != nil {
		log.Fatalf("加载配置文件失败: %v", err)
	}

	// 创建WebSocket服务器
	wsserver := ws.NewWebSocketServer(&cfg.Server)

	// 创建币安WebSocket客户端，并设置消息处理器
	binanceClient := binance.NewBinanceClient(&cfg.Binance, func(data []byte) {
		// 处理从币安接收到的消息
		handleBinanceMessage(data, wsserver)
	})

	// 启动币安客户端
	if err := binanceClient.Start(); err != nil {
		log.Fatalf("启动币安客户端失败: %v", err)
	}
	defer binanceClient.Stop()

	// 设置信号处理，优雅关闭
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)

	// 启动WebSocket服务器（在协程中）
	serverErrCh := make(chan error, 1)
	go func() {
		if err := wsserver.Start(); err != nil {
			serverErrCh <- fmt.Errorf("WebSocket服务器启动失败: %v", err)
		}
	}()

	// 等待信号或错误
	select {
	case err := <-serverErrCh:
		log.Fatal(err)
	case sig := <-sigCh:
		log.Printf("接收到信号: %v, 正在关闭服务器...", sig)
		wsserver.Stop()
		binanceClient.Stop()
	}

	log.Println("服务器已优雅关闭")
}

// handleBinanceMessage 处理从币安接收到的消息
func handleBinanceMessage(data []byte, wsserver *ws.WebSocketServer) {
	// log.Printf("接收到币安消息: %s", string(data))
	// 解析消息，确定消息类型
	var msg map[string]interface{}
	if err := json.Unmarshal(data, &msg); err != nil {
		log.Printf("解析币安消息失败: %v", err)
		return
	}

	// 根据消息类型发布到不同的频道
	if klineData, ok := msg["k"]; ok {
		// K线数据
		klineMap, ok := klineData.(map[string]interface{})
		if !ok {
			log.Printf("K线数据格式错误")
			return
		}
		symbol, ok := klineMap["s"].(string)
		if !ok {
			log.Printf("无法获取K线数据的symbol")
			return
		}
		interval, ok := klineMap["i"].(string)
		if !ok {
			log.Printf("无法获取K线数据的interval")
			return
		}
		channel := fmt.Sprintf("kline_%s_%s", symbol, interval)
		// log.Printf("发布K线数据到频道: %s", channel)
		wsserver.Publish(channel, data)
	} else if event, ok := msg["e"].(string); ok {
		switch event {
		case "depthUpdate":
			// 深度数据
			symbol, ok := msg["s"].(string)
			if !ok {
				log.Printf("无法获取深度数据的symbol")
				return
			}
			channel := fmt.Sprintf("depth_%s", symbol)
			// log.Printf("发布深度数据到频道: %s", channel)
			wsserver.Publish(channel, data)
		case "trade":
			// 交易数据
			symbol, ok := msg["s"].(string)
			if !ok {
				log.Printf("无法获取交易数据的symbol")
				return
			}
			channel := fmt.Sprintf("trade_%s", symbol)
			// log.Printf("发布交易数据到频道: %s", channel)
			wsserver.Publish(channel, data)
		default:
			// 其他类型的消息
			log.Printf("接收到未知类型的币安消息事件: %s", event)
		}
	} else {
		// 其他类型的消息
		log.Printf("接收到无法识别的币安消息")
	}
}
